package com.amrit.pojos;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.service.ServiceRegistryBuilder;

public class ManageEmployee {
	private static SessionFactory sessionFactory;
	private static Configuration configuration;

	public static void main(String[] args) {
		try {
			configuration = new Configuration();
			configuration.configure();
			org.hibernate.service.ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
			sessionFactory = configuration.buildSessionFactory(serviceRegistry);
			//factory = new Configuration().configure().buildSessionFactory();
		} catch (Throwable ex) {
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
		}
		ManageEmployee ME = new ManageEmployee();

		/* Add few employee records in database */
		ME.addEmployee("Zara", "Ali", 2000);
		ME.addEmployee("Daisy", "Das", 5000);
		ME.addEmployee("John", "Paul", 5000);
		ME.addEmployee("Mohd", "Yasee", 3000);

		/* List down all the employees */

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		ME.listEmployees();
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

		/* Print Total employee's count */
		ME.countEmployee();

		/* Print Total salary */
		ME.totalSalary();
	}

	/* Method to CREATE an employee in the database */
	public Integer addEmployee(String fname, String lname, int salary) {
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		Integer employeeID = null;
		try {
			tx = session.beginTransaction();
			Employee employee = new Employee(fname, lname, salary);
			employeeID = (Integer) session.save(employee);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
		return employeeID;
	}

	/* Method to READ all the employees having salary more than 2000 */
	@SuppressWarnings("rawtypes")
	public void listEmployees() {
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Employee.class);
			cr.setFirstResult(2);
			cr.setMaxResults(6);
			// Add restriction.
			cr.add(Restrictions.gt("salary", 2000));
			List employees = cr.list();

			for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
				Employee employee = (Employee) iterator.next();
				System.out.print("First Name: " + employee.getFirstName());
				System.out.print("  Last Name: " + employee.getLastName());
				System.out.println("  Salary: " + employee.getSalary());
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

	/* Method to print total number of records */
	@SuppressWarnings("rawtypes")
	public void countEmployee() {
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Employee.class);

			// To get total row count.
			cr.setProjection(Projections.rowCount());
			List rowCount = cr.list();

			System.out.println("Total Count: " + rowCount.get(0));
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

	/* Method to print sum of salaries */
	@SuppressWarnings("rawtypes")
	public void totalSalary() {
		Session session = sessionFactory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Employee.class);

			// To get total salary.
			cr.setProjection(Projections.sum("salary"));
			List totalSalary = cr.list();

			System.out.println("Total Salary: " + totalSalary.get(0));
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
}